package com.pyue.eam.admin.utils;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.pyue.eam.admin.api.except.ApiAsserts;
import com.pyue.eam.admin.mapper.EamHolidayMapper;
import com.pyue.eam.common.core.constant.CacheConstants;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 工具类
 */
@AllArgsConstructor
@Component
public class HolidayUtil {
    private final RedisTemplateUtil redisTemplateUtil;
    private final EamHolidayMapper eamHolidayMapper;

    public String holidayNameByDate(LocalDate date) {
        return eamHolidayMapper.getHolidayName(date.toString());
    }

    public Double overTimeHour(LocalTime start, LocalTime end) {
        ApiAsserts.isTrue(start.isBefore(end), "开始时间不能大于结束时间");
        // 工作时间 08:30 17:00
        final LocalTime workStart = LocalTime.of(8, 30);
        final LocalTime workEnd = LocalTime.of(17, 0);


        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startDateTime = null;
        LocalDateTime endDateTime = null;

        // 工作范围内
        if (!start.isBefore(workStart) && !start.isAfter(workEnd) && !end.isAfter(workEnd)) {
            return 0.0;
        }

        // 前后跨越工作区
        if (!start.isAfter(workStart) && !end.isBefore(workEnd)) {
            return overTimeHour(start, workStart) + overTimeHour(workEnd, end);
        }

        AtomicBoolean okFlag = new AtomicBoolean(false);

        // 全部前工作区
        if (!start.isAfter(workStart) && !end.isAfter(workStart)) {
            startDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), start.getHour(), start.getMinute());
            endDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), end.getHour(), end.getMinute());
            okFlag.set(true);
        } else if (!start.isBefore(workEnd)) {
            // 全部后工作区
            startDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), start.getHour(), start.getMinute());
            endDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), end.getHour(), end.getMinute());
            okFlag.set(true);
        } else if (start.isBefore(workStart) && !end.isAfter(workEnd)) {
            // 单跨前工作区
            startDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), start.getHour(), start.getMinute());
            endDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), workStart.getHour(), workStart.getMinute());
            okFlag.set(true);
        } else if (start.isAfter(workStart) && !start.isAfter(workEnd) && !end.isBefore(workEnd)) {
            // 单跨后工作区
            startDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), workEnd.getHour(), workEnd.getMinute());
            endDateTime = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), end.getHour(), end.getMinute());
            okFlag.set(true);
        }

        ApiAsserts.isTrue(okFlag.get(), "时间匹配错误");

        return workHourCount(startDateTime, endDateTime);
    }

    /**
     * 区间间隔小时
     */
    public static double workHourCount(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        long dateTime = EamDateUtil.betweenLocalDateTime(startDateTime, endDateTime, DateUnit.MINUTE);
        System.out.println("加班小时" + dateTime + "分钟");
        // return BigDecimal.valueOf(dateTime).divide(BigDecimal.valueOf(60L), 3).doubleValue();
        return NumberUtil.div(dateTime, 60L, 2);
    }

    /**
     * 是否是加价天 周六日和节假日都算加班日
     */
    public boolean isPlusPriceDay(LocalDate localDate) {
        // 是否节假日
        boolean holiday = isHoliday(localDate);

        if (holiday) {
            return Boolean.TRUE;
        } else {
            // 不是法定节假日情况下
            boolean legalWorkday = isLegalWorkday(localDate);
            if (legalWorkday) {
                return Boolean.FALSE;
            }
        }

        // 是否周末
        return DateUtil.isWeekend(EamDateUtil.parseDate(localDate));
    }

    /**
     * 节假日
     */
    private boolean isHoliday(LocalDate localDate) {
        List<String> holidayList;
        String holidayKey = CacheConstants.GLOBALLY + "eam:holiday";
        if (redisTemplateUtil.exists(holidayKey)) {
            holidayList = redisTemplateUtil.getAllList(holidayKey);
        } else {
            int year = localDate.getYear();
            holidayList = eamHolidayMapper.getHolidayList(year);
            redisTemplateUtil.setListAll(holidayKey, holidayList);
        }
        return holidayList.contains(localDate.toString());
    }

    /**
     * 工作日
     */
    private boolean isLegalWorkday(LocalDate localDate) {
        List<String> legalWorkDayList;
        String workDayKey = CacheConstants.GLOBALLY + "eam:legalWorkDay";
        if (redisTemplateUtil.exists(workDayKey)) {
            legalWorkDayList = redisTemplateUtil.getAllList(workDayKey);
        } else {
            int year = localDate.getYear();
            legalWorkDayList = eamHolidayMapper.getWorkdayList(year);
            redisTemplateUtil.setListAll(workDayKey, legalWorkDayList);
        }

        return legalWorkDayList.contains(localDate.toString());
    }
}
